package main

import (
	"context"
	"fmt"
	"runtime"
	"time"
)

func monitor2(ctx context.Context, index int) {
	for {
		select {
		case v := <-ctx.Done():
			fmt.Printf("monitor2: %v, the received channel value is: %v, ending\n", index, v)
			return
		default:
			fmt.Printf("monitor2: %v, in progress...\n", index)
			time.Sleep(time.Second)
		}
	}
}

func monitor1(ctx context.Context, index int) {
	for {
		go monitor2(ctx, index)

		select {
		case v := <-ctx.Done():
			fmt.Printf("monitor1: %v, the received channel value is: %v, ending\n", index, v)
			return
		default:
			fmt.Printf("monitor1: %v, in progress...\n", index)
			time.Sleep(time.Second)
		}
	}
}

func main() {
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(1*time.Second))

	defer cancel()

	for i := 1; i <= 5; i++ {
		go monitor1(ctx, i)
	}

	time.Sleep(1 * time.Second)

	if ctx.Err() != nil {
		fmt.Println("the cause of cancel is: ", ctx.Err())
	}

	fmt.Println(runtime.NumGoroutine())
	println("main program exit!!")
}
